﻿/*
Copyright (c) 2005-2008, CellAO Team

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    * Neither the name of the CellAO Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

using System;
using System.Collections.Generic;
using System.Text;
using AO.Core;

/*
 *
 * 
 * 
 *          PLEASE DO NOT TOUCH THIS CODE RIGHT NOW!
 *          DNIFAN IS WORKING ON IT AND YOU MIGHT MESS IT UP SO FAR HE
 *          DOESN'T KNOW HIS WAY AROUND ANYMORE :P
 *          
 *          Thanks!
 * 
 *  
 * 
 */

namespace ZoneEngine.NPC
{
    /// <summary>
    /// 
    /// </summary>
    public class MobType : NPCType
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="c"></param>
        public override void BroadcastPF(Client c)
        {
            NPCPool.RegisterMob(this);
            base.BroadcastPF(c);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="c"></param>
        public override void SendToClient(Client c)
        {
            PacketWriter _writer = new PacketWriter();

            #region Header

            _writer.PushByte(0xDF); _writer.PushByte(0xDF);
            _writer.PushShort(10);
            _writer.PushShort(1);
            _writer.PushShort(0);   // length. writer will take care of this
            _writer.PushInt(3086);  // sender. our server ID
            _writer.PushInt(c.Character.characterId);  // receiver
            _writer.PushInt(0x271B3A6B);    // packet ID
            _writer.PushIdentity(50000, DynelID); // affected identity
            _writer.PushByte(0);    // End of Header

            #endregion

            _writer.PushByte(0x36); //Packet Version

            #region Flags
            //flags set by bitconverter
            //00000010
            _writer.PushByte(Misc.BitsToByte.Convert(false, false, false, false, false, false, true, false)); //00000010 (0x02)
            //00101011
            _writer.PushByte(Misc.BitsToByte.Convert(false, false, true, false, true, false, true, true)); //(0x2B)
            //01101010
            _writer.PushByte(Misc.BitsToByte.Convert(false, true, true, false, true, false, true, false)); //(0x6A)
            //01000011
            _writer.PushByte(Misc.BitsToByte.Convert(false, true, false, false, false, false, true, true)); //(0x43)
            #endregion

            #region Position

            _writer.PushInt(pf);
            _writer.PushCoord(coord);
            _writer.PushQuat(heading);

            #endregion

            _writer.PushBytes(new byte[]
            {
                //unknown stuff (yet :P)
                0x00, 0x00, 0x04, 0xCB,
            });

            #region Name
            _writer.PushByte((byte)(Name.Length + 1));
            _writer.PushBytes(Encoding.ASCII.GetBytes(Name));
            _writer.PushByte(0);
            #endregion

            //NPC flags
            _writer.PushInt(0x10081201);
            //account flags
            _writer.PushShort(0);
            //expansions
            _writer.PushShort(0);

            _writer.PushBytes(new byte[] 
            {
                0xDC, 0x00, 0x00, 0x00, 
                
                //level (if I push them in the writer, client crashes, dunno why O_o)
                0x00, 0x0B,
                //health
                0x01, 0x1C, 
                //shit
                0x00,
            });

            //_writer.PushShort(Level);
            //_writer.PushShort(Health);
            //_writer.PushByte(0);

            //0x00, 0x03, 0xD7, 0x86, 0x00,

            #region Appearance

            _writer.PushInt(MonsterData);

            _writer.PushShort(MonsterScale);

            #endregion

            _writer.PushBytes(new byte[] 
            {                
                0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1C,
                0x40, 0x82, 0x6D, 0xD6, 0xBC, 0x90, 0x58, 0x23,
                0x40, 0x57, 0x5E, 0x84, 0x03, 0x02, 0x01, 0x01,
                0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 
                0x00, 0x02, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00,
                0x03, 0xF1, 
                
                //some type for the waypoints?
                0x00, 0x00, 0xC3, 0x50, 
            });

            #region Waypoints

            //the mob's ID for some reason O_o
            _writer.PushInt(DynelID);

            /*          WAYPOINTS           */
            _writer.PushInt(1 + WaypointCounter); //amount of waypoints
            //initial waypoint (main)
            _writer.PushCoord(coord);

            for (int i = 0; i < WaypointCounter; i++)
            {
                _writer.PushCoord(Waypoints[i]);
            }
            /*      END WAYPOINTS           */

            #endregion

            #region Texturing

            //TEXTURING:
            _writer.Push3F1Count(5);

            _writer.PushInt(0);
            _writer.PushInt(0); //insert textures here later
            _writer.PushInt(0);

            _writer.PushInt(1);
            _writer.PushInt(0); //insert textures here later
            _writer.PushInt(0);

            _writer.PushInt(2);
            _writer.PushInt(0); //insert textures here later
            _writer.PushInt(0);

            _writer.PushInt(3);
            _writer.PushInt(0); //insert textures here later
            _writer.PushInt(0);

            _writer.PushInt(4);
            _writer.PushInt(0); //insert textures here later
            _writer.PushInt(0);

            //HEAD MESH:
            //MOB HAS NONE:
            _writer.Push3F1Count(0);

            #endregion

            //packetFlags2
            _writer.PushInt(0);

            byte[] reply = _writer.Finish();

            c.CmpStream.Write(reply, 0, reply.Length);
            c.CmpStream.Flush();

            //now send a packet to notify client of new NPC
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mobID"></param>
        /// <returns></returns>
        public override bool NPCInit(int mobID)
        {
            MySqlWrapper mySql = new MySqlWrapper();

            mySql.MySqlRead("SELECT * FROM mobtemplate WHERE ID = " + mobID + ";");

            if (mySql.myreader.Read() == false)
            {
                return false;
            }

            string name = mySql.myreader.GetString("Name");
            short health = (short)mySql.myreader.GetInt32("MaxHealth");
            MonsterData = mySql.myreader.GetInt32("MonsterData");

            //when the stuff is not entered correctly in DB
            if (health == 0)
            {
                health = 100;
            }

            mySql.mcc.Close();
            mySql.myreader.Close();

            Name = name;
            Health = health;
            RunningSpeed = 0;
            //MonsterScale = 90;

            Waypoints = new AOCoord[MAX_WAYPOINTS];

            return true;
        }

        /// <summary>
        /// Hook to call when this Mob is being attacked by a Client
        /// </summary>
        /// <param name="c">Client that is attacking</param>
        public void OnAttack(Client c)
        {
            //Put follow packet here.
        }

        /// <summary>
        /// Hook to call when the mob is being attacked by a other NPC
        /// </summary>
        /// <param name="npc">Other NPC</param>
        public void OnAttack(NPCType npc)
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="coordinates"></param>
        public void AddWaypoint(AOCoord coordinates)
        {
            if (WaypointCounter == MAX_WAYPOINTS)
            {
                System.Console.WriteLine("Maximum amount of Waypoints for this Mob has been reached: {0}.", MAX_WAYPOINTS);
                return;
            }

            Waypoints[WaypointCounter] = coordinates;
            WaypointCounter++;
        }

        public AOCoord[] Waypoints;
        private int WaypointCounter = 0;

        //changable:
        internal int MAX_WAYPOINTS = 64;
    }
}

